package edu.qqcui.study.config;


import edu.qqcui.study.bean.Color;
import edu.qqcui.study.bean.Person;
import edu.qqcui.study.bean.Red;
import edu.qqcui.study.condition.*;
import org.springframework.context.annotation.*;
import org.springframework.context.annotation.ComponentScan.Filter;

/**
 * 配置类就相当于以前的配置文件
 *
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021-06-26 10:36
 **/
@Configuration // 告诉spring，这是一个配置类
@Conditional({WindowsCondition.class})

@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {

	/**
	 *
	 * ConfigurableBeanFactory.SCOPE_PROTOTYPE,  "prototype"
	 * ConfigurableBeanFactory.SCOPE_SINGLETON,  "singleton"
	 * org.springframework.web.context.WebApplicationContext.SCOPE_REQUEST,  "request"
	 * org.springframework.web.context.WebApplicationContext.SCOPE_SESSION   "session"
	 *
	 * prototype : ioc容器启动的时候，不回去调用方法创建对象放到容器中，只有在获取的时候才会创建实例，而且是每次获取都会创建一个新的实例
	 * singleton ： ioc容器启动的时候调用方法创建实例并放到容器中，每次获取的时候，只是从ioc容器中拿出来
	 * request ： 一次请求中创建一个实例
	 * session ： 一个session中创建一个实例
	 * @return Person类的一个实例
	 *
	 * @Scope : 使用该注解，调整作用域
	 * @Lazy : 使用该注解，调整是否懒加载，该注解只适用于单实例的作用域
	 *         单实例作用域，在IOC容器启动完成的时候创建实例，如果添加该注解，则在第一次使用（调用）bean的时候创建实例
	 */
//	@Scope("prototype")
	@Lazy
	@Bean(value = "person")
	public Person getPerson() {
		System.out.println("创建Person对象的实例……");
		return new Person("张三", 28);
	}

	/**
	 * @Conditional : 满足对应的条件才会生成对应的对象实例并放到容器中，可以用到方法上和类上
	 * 只有在操作系统是Windows服务器时，才会创建bill的Person实例
	 * @return bill
	 */
	@Conditional({WindowsCondition.class})
	@Bean(value = "bill")
	public Person getBill() {
		return new Person("Bill Gates", 62);
	}

	/**
	 * 只有在操作系统为Linux时，才会创建linus的Person实例
	 * @return linus
	 */
	@Conditional(LinuxCondition.class)
	@Bean(value = "linus")
	public Person getLinus() {
		return new Person("Linus", 48);
	}

	/**
	 * 给容器中注册组件的方式：
	 * 1）包扫描+组件标注注解（@Controller, @Service, @Repository, @Component等等），适用于自己写的组件
	 * 2）@Bean的方式，适用于导入第三方包中的组件
	 * 3）@Import，快速给容器中导入一个组件
	 *      1）@Import(要导入容器中的组件) ： 容器中会自动注册这个组件，id默认时全类名
	 *      2）实现 ImportSelector 接口 : 返回需要导入组件的全类名数组
	 *      3）实现 ImportBeanDefinitionRegistrar 接口 ： 手动注册bean到容器中
	 * 4)使用Spring提供的FactoryBean（工厂Bean）
	 *      1)默认获取到的是调用getObject方法创建的对象
	 *      2）如果需要获取工厂Bean本身，需要在id前面加一个前缀&
	 *          &colorFactoryBean
	 */
	@Bean
	public ColorFactoryBean colorFactoryBean() {
		return new ColorFactoryBean();
	}
}
